<template>
  <div class="play">
    <!-- 模糊背景 -->
    <div
      class="song-bg"
      :style="`background-image: url(${songInfo.albUrl});`"
    ></div>
    <!-- :style="`background-image: url(${songInfo.albUrl});`" -->
    <!-- 播放页顶部导航 -->
    <div class="header">
      <van-icon
        name="arrow-left"
        size="20"
        class="left-icon"
        @click="$router.back()"
      />
    </div>
    <!-- 留声机--容器 -->
    <div class="song-wrapper">
      <!-- 留声机--靠CSS旋转 -->
      <div
        class="song-turn anni"
        :style="`animation-play-state:${playStatus ? 'running' : 'paused'}`"
      >
        <div class="song-img">
          <img style="width: 100%" :src="songInfo.albUrl" alt="" />
        </div>
      </div>
      <!-- 播放按钮 -->
      <div class="start-box" @click="audioStart">
        <span class="song-start" v-show="!playStatus"></span>
      </div>
      <!-- 播放歌词的容器 -->
      <div class="song-msg">
        <!-- 歌曲名字 -->
        <h2 class="m-song-h2">
          <span class="song-name">
            {{ songInfo.songName }}-{{ songInfo.artName }}
          </span>
        </h2>
        <!-- 播放歌词的部分 随着时间切换展示一句歌词-->
        <div class="lrcContent">
          <div
            class="container"
            :style="`transform:translateY(${transDistance}px)`"
          >
            <p
              :class="['lrc', currentIndex == key ? 'currentLrc' : '']"
              v-for="(value, key, index) in lyric"
              :key="index"
            >
              {{ value }}
            </p>
          </div>
        </div>
      </div>
      <!-- 控制区域 -->
      <div class="control">
        <div class="tool">
          <!-- 下载按钮 -->
          <van-icon name="upgrade" class="download" @click="download" />
        </div>
        <!-- 播放进度条 -->
        <div class="progress">
          <!-- <van-progress :percentage="50" stroke-width="2px" :show-pivot=false @click.native="clickProgress"/> -->
          <!-- 全长进度条 -->
          <div class="process-bar"></div>
          <!-- 增长的进度条 -->
          <div class="growing-bar" :style="`width:${processPersent}%`"></div>
          <!-- 进度条文字 -->
          <div
            class="bar-txt"
            id="barTxt"
            :style="`transform:translate(${
              (processPersent / 100) * processBarWidth
            }px,-50%)`"
          ></div>
        </div>
        <div class="play-control"></div>
      </div>
      <!-- 留声机的唱臂 -->
      <div class="needle" :style="`transform:rotate(${needleDeg})`"></div>
      <!-- 真实的播放元素 -->
      <audio :src="songUrl" ref="audio" preload="true"></audio>
    </div>
  </div>
</template>

<script>
import { getSongUrl } from "@/server/api/HomeApi.js";
import {
  getLyricById,
  getSongDetail,
  getSongStream,
} from "@/server/api/PlayApi.js";
import { mapGetters } from "vuex";
import { Throttle } from "@/utils/Debounce.js";
import { streamToBlob } from "@/utils/tools.js";
export default {
  data() {
    return {
      songUrl: "",
      //   播放状态 false没播放
      playStatus: false,
      //   当前播放的歌词
      currentIndex: 0,
      //   歌曲信息
      songInfo: {},
      //   歌词信息
      lyric: {},
      //   歌词平移的距离
      transDistance: 0,
      // 歌曲时间，单位秒
      songDuration: 1,
      // 当前歌曲时间
      currentTime: 0,
      // 进度条总长度
      processBarWidth: 257,
      // 当前歌词块的高度
      curLyricHeight: 0,
    };
  },
  methods: {
    //   播放音乐
    audioStart() {
      if (this.playStatus) {
        // 暂停
        this.$refs.audio.pause();
      } else {
        // 播放
        this.$refs.audio.play();
        // 如果歌词在下面就让它回到上面
        if (this.$refs.audio.currentTime == 0) {
          this.transDistance = 0;
        }
      }
      this.playStatus = !this.playStatus;
      console.log("播放暂停", this.playStatus);
    },
    // formatLyric--格式化歌词
    formatLyric(lyricStr) {
      // console.log(lyricStr );
      let reg = /\[.+?\]/g;
      // 匹配所有[]自负串以及里面的一切内容，返回数组
      let timeArr = lyricStr.match(reg);
      // ["[00:00.000]", "[00:01.000]", ......]
      // console.log(timeArr);
      // 按照[]拆分歌词字符串, 返回一个数组(下标为0位置元素不要,后面的留下所以截取)
      let contentArr = lyricStr.split(/\[.+?\]/).slice(1);
      // console.log(contentArr);

      // 保存歌词的对象, key是秒, value是显示的歌词
      let lyricObj = {};
      timeArr.forEach((item, index) => {
        // 拆分[00:00.000]这个格式字符串, 把分钟数字取出, 转换成秒
        let ms = item.split(":")[0].split("")[2] * 60;
        // 拆分[00:00.000]这个格式字符串, 把十位的秒拿出来, 如果是0, 去拿下一位数字, 否则直接用2位的值
        let ss =
          item.split(":")[1].split(".")[0].split("")[0] === "0"
            ? item.split(":")[1].split(".")[0].split("")[1]
            : item.split(":")[1].split(".")[0];
        // 秒数作为key, 对应歌词作为value
        lyricObj[ms + Number(ss)] = contentArr[index];
      });
      // console.log("歌词", lyricObj);
      return lyricObj;
    },
    // 展示歌词
    showLyric() {
      // 添加监听事件,控制歌词的显示
      let fn = Throttle(() => {
        let currentTime = Math.floor(this.$refs.audio.currentTime);
        this.currentTime = currentTime;
        if (this.lyric[currentTime]) {
          this.currentIndex = currentTime;
        } else {
          this.curLyric = this.lastLy;
        }
      }, 1000);
      this.$refs.audio.addEventListener("timeupdate", fn);
    },
    // 点击进度条
    clickProgress(event) {
      console.log("click Prog", event);
    },
    // 下载歌曲
    async download() {
      let res = await getSongStream(this.songUrl);
      // console.log('download',res);
      streamToBlob(res, this.songInfo.songName);
    },
    /**
     * 获取元素已有的偏移量
     */
    getTranslateXY(element) {
      const style = window.getComputedStyle(element);
      const matrix = new DOMMatrixReadOnly(style.transform);
      return {
        translateX: matrix.m41,
        translateY: matrix.m42,
      };
    },
    /**
     * 检查X有没有越界，越界就不让移动了
     */
    checkOver(moveX, target) {
      let progress = document.querySelector(".progress");
      let totalWidth = progress.offsetWidth || progress.clientWidth;
      // 记录
      this.processBarWidth = totalWidth;
      // console.log('宽度是啥：',totalWidth);
      let transX = target.offsetLeft + moveX;
      let totalX = transX + (target.offsetWidth || target.clientWidth);

      if (transX < 0) {
        // 小于0了就移动   到原点的距离
        moveX = target.offsetLeft;
        console.log("小于", moveX);
      } else if (totalX > totalWidth) {
        moveX = totalWidth - target.offsetLeft - target.offsetWidth;
        console.log("大于", moveX, "totalX");
      }
      return { moveX, totalWidth };
    },
    // 拖动歌词的进度条
    tiggleProcess(event) {
      // 加上这个的话会导致点击时的active样式不生效
      // event.preventDefault();
      event.stopPropagation();
      event = event || window.event;
      let isMove = true;
      // 获取已有的偏移量
      let { translateX } = this.getTranslateXY(event.target);
      let startLeft = event.pageX || event.touches[0].pageX;
      // 减去原来的偏移量
      startLeft -= translateX;
      // 按住的时候，暂停播放，不然问题好多
      this.$refs.audio.pause();
      this.playStatus = false;
      // 记录一下拖动之后的百分比，
      let persentage = 0;
      let hasMove = false;
      document.ontouchmove = (e) => {
        e = e || window.event;
        // console.log('move了',isMove,node);
        if (isMove) {
          let newLeft = e.pageX || e.touches[0].pageX;
          let finX = newLeft - startLeft;
          let { moveX, totalWidth } = this.checkOver(finX, e.target);
          console.log("moveX", moveX, "totalWidth", totalWidth);
          persentage = moveX / totalWidth;
          console.log("persentage", persentage);
          e.target.style = `transform:translate(${moveX}px,-50%)`;
          hasMove = true;
        }
      };
      document.ontouchend = () => {
        console.log("ontouchend");
        if (hasMove) {
          // 移动了才做这个事，不移动就不更改时间
          this.$refs.audio.currentTime = persentage * this.songDuration;
        }
        isMove = false;
        this.$refs.audio.play();
        this.playStatus = !this.playStatus;
        document.ontouchmove = null;
        document.ontouchend = null;
      };
    },
  },
  computed: {
    // ...mapState(["songInfo"]),
    ...mapGetters(["albUrl"]),
    // 留声机唱臂的角度
    needleDeg() {
      return this.playStatus ? "-7deg" : "-38deg";
    },
    // 计算进度条的位置
    processPersent() {
      let percentage = (this.currentTime / this.songDuration) * 100;
      return percentage.toFixed(2);
    },
  },
  watch: {
    currentIndex: {
      handler: function (newV, oldV) {
        if (newV != oldV) {
          this.transDistance = this.transDistance - this.curLyricHeight;
          const lyric = document.querySelector(".currentLrc");
          this.curLyricHeight = lyric.offsetHeight;
          console.log("this.curLyricHeight", this.curLyricHeight);
          console.log("lyric", lyric);
          console.dir("lyric", lyric);
        }
      },
      immediate: true,
    },
  },
  async mounted() {
    let url = await getSongUrl(this.$route.query.songId);
    this.songUrl = url && url.data && url.data.data ? url.data.data[0].url : "";
    console.log(this.songUrl);

    // 获取歌词详情
    let lyricRes = await getLyricById(this.$route.query.songId);
    let lyricStr = lyricRes.data.lrc.lyric;
    this.lyric = this.formatLyric(lyricStr);
    // 展示歌词
    this.showLyric();
    // 获取歌曲详情
    let songDetail = await getSongDetail(this.$route.query.songId);
    this.songInfo = {
      songName: songDetail.data.songs[0].name,
      artName: songDetail.data.songs[0].ar[0].name,
      albUrl: songDetail.data.songs[0].al.picUrl,
    };

    // 添加自动播放和结束暂停旋转
    let arro = () => {
      /* 音频可以播放；如果权限允许则播放 */
      console.log("开始播放了", this.playStatus);
      this.audioStart();
      this.$refs.audio.removeEventListener("canplay", arro);
    };

    let endFn = () => {
      this.playStatus = !this.playStatus;
      console.log("结束播放了", this.playStatus);
    };
    let audio = this.$refs.audio;
    audio.load();
    audio.addEventListener("canplay", arro);
    audio.addEventListener("ended", endFn);
    audio.addEventListener("durationchange", () => {
      this.songDuration = audio.duration;
      console.log("this.songDuration", this.songDuration);
    });

    // 禁用长按菜单
    window.addEventListener("contextmenu", function (e) {
      e.preventDefault();
    });
    document.body.addEventListener("touchstart", () => {});
    // 增加监听
    document
      .querySelector("#barTxt")
      .addEventListener("touchstart", this.tiggleProcess);
  },
};
</script>

<style>
.play {
  width: 100%;
  overflow: hidden;
}
.song-bg {
  background-color: #161824;
  background-position: 50%;
  background-repeat: no-repeat;
  background-size: auto 100%;
  transform: scale(1.5);
  transform-origin: center;
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  z-index: 1;
  opacity: 1;
  filter: blur(10px);
}
/* 给背景加上一层灰色遮罩，不然白色背景，白色文字看不清 */
.song-bg::before {
  content: "";
  background-color: rgba(0, 0, 0, 0.3);
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
}
.header {
  height: 50px;
}
.left-icon {
  position: absolute;
  top: 10px;
  left: 10px;
  font-size: 24px;
  z-index: 10001;
  color: #fff;
  padding: 5px;
  border-radius: 20px;
  background-color: rgba(200, 192, 192, 0.345);
  box-shadow: 0px 0px 5px #fff;
}
/* 唱片部分 */
.song-wrapper {
  position: fixed;
  width: 247px;
  height: 247px;
  top: 51px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9;
}
/* 唱片 */
.song-turn {
  width: 100%;
  height: 100%;
  background: url("./img/bg.png") no-repeat;
  background-size: 100%;
}
/* 唱片上的图片 */
.song-img {
  width: 154px;
  height: 154px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  overflow: hidden;
  border-radius: 50%;
}
/* 唱片旋转 */
@keyframes turn {
  0% {
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
  }
}
.anni {
  animation: turn 15s linear infinite;
  animation-fill-mode: backwards;
}
/* 播放按钮 */
.start-box {
  position: absolute;
  width: 156px;
  height: 156px;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  justify-content: center;
  align-items: center;
}
/* 播放按钮的图片 */
.song-start {
  width: 56px;
  height: 56px;
  background: url("./img/start.png");
  background-size: contain;
}
/* 歌曲名称 */
.m-song-h2 {
  margin-top: 20px;
  text-align: center;
  font-size: 18px;
  color: #fefefe;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* 唱臂 */
.needle {
  position: absolute;
  top: -40px;
  left: 50%;
  /* transform: translateX(-50%); */
  transform-origin: 10px 10px;
  background: url("./img/needle-ab.png");
  background-size: contain;
  width: 73px;
  height: 118px;
  transition: all 0.6s;
}
/* 歌词部分 */
.lrcContent {
  margin-top: 50px;
  height: 200px;
  overflow: hidden;
  text-align: center;
}
.lrc {
  font-size: 14px;
  color: rgba(211, 211, 211, 0.782);
  /* height: 30px; */
  line-height: 30px;
}
.currentLrc {
  font-size: 14px;
  color: #fff;
}
.container {
  padding-top: 62px;
  transition: all 0.5s linear;
}
.tool {
  text-align: center;
}
/* 进度条 */
.progress {
  margin-top: 30px;
  position: relative;
}
.process-bar {
  height: 1px;
  background-color: lightgrey;
  border-radius: 5px;
}
.growing-bar {
  background-color: #fff;
  height: 1px;
}
.bar-txt {
  position: absolute;
  top: 0;
  transform: translateY(-50%);
  height: 6px;
  width: 6px;
  border-radius: 10px;
  background-color: #fff;
  transition: all 0.1s linear;
  z-index: 99;
}
.bar-txt:active {
  height: 15px;
  width: 15px;
}
/* 下载按钮 */
.download {
  margin-top: 30px;
  font-size: 30px;
  color: #fff;
  transform: rotate(180deg);
  transition: all 0.1s linear;
  height: 30px;
}
.download:active {
  box-shadow: 0 0 10px;
  border-radius: 50%;
}
</style>
